package org.tissou.server.Utils;

import org.tissou.client.Services.MonnaieInfos;
import org.tissou.client.Services.TauxConversionInfos;
import org.tissou.client.Services.MonException;

import java.util.Date;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.text.SimpleDateFormat;
import java.text.DateFormat;
import java.net.URL;
import java.net.MalformedURLException;
import java.net.URLConnection;
import java.io.InputStream;
import java.io.IOException;
import java.sql.SQLException;
import java.sql.ResultSet;

/**
 * Created by IntelliJ IDEA.
 * User: Manu
 * Date: 10 janv. 2009
 * Time: 11:37:56
 * To change this template use File | Settings | File Templates.
 */
public class TelechargeurDeTaux {

   /**
   * L'URL ou on va chercher le machin
   * la date doit etre au format : MM-dd-yyyy
   */
  //static final String url =  "http://www.exchange-rates.org/Rate/GBP/EUR/%s";
  static final String url =  "http://www.exchange-rates.org/Rate/%s/%s/%s";

  static final String BASE_SQL = "INSERT INTO tauxconversion VALUES ('%s', '%s', '%s', '%f')";

  static final DateFormat SQL_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");

  public TauxConversionInfos telechargerTauxPourDate(MonnaieInfos monnaie_initiale,
                                                     MonnaieInfos monnaie_finale, Date date) {
    if (date.after(new Date())) {
      throw new MonException("La date est dans le futur, on ne peut obtenir de taux de conversion.");
    }
    else{
      SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy");
      String dateString = dateFormat.format(date);

      try {
        URL urlObject =  new URL(String.format(url, monnaie_initiale.getCodeMonnaie(),
            monnaie_finale.getCodeMonnaie(), dateString));
        System.out.println(urlObject);
        URLConnection connection = urlObject.openConnection();
        InputStream urlStream = connection.getInputStream();
        int c = 0;
        StringBuffer buf = new StringBuffer();
        do {
          c = urlStream.read();
          buf.append((char)c);
        }
        while (c != -1);

        urlStream.close();
        return analysePage(buf.toString(), monnaie_initiale, monnaie_finale, date);
      } catch (MalformedURLException e) {
        throw new MonException("On s'est plantes dans l'URL", e);
      } catch (IOException e) {
        throw new MonException("Impossible de lire l'URL", e);
      }
    }
  }

  private TauxConversionInfos analysePage(String s, MonnaieInfos monnaie_initiale,
                                                     MonnaieInfos monnaie_finale, Date date) {
    //Pattern p = Pattern.compile(String.format("1,000,000 %s = ([\\d,\\.]+) %s",
      //      monnaie_initiale.getCodeMonnaie(), monnaie_finale.getCodeMonnaie()), Pattern.CASE_INSENSITIVE);
    //System.out.println(s);
    Pattern p = Pattern.compile("1,000,000 [A-Z]{3} = ([\\d,\\.]+) [A-Z]{3}", Pattern.CASE_INSENSITIVE);

    Matcher m = p.matcher(s);
    if (!m.find() || m.groupCount() < 1) {
        throw new MonException("Je ne trouve pas les taux dans la page.");
    } else {
      String nombre = m.group(1);
      nombre = nombre.replace(",", "");
      return new TauxConversionInfos(date, monnaie_initiale, monnaie_finale, Float.valueOf(nombre)/1000000f);
    }
  }

  public void insererTauxDansLaTable(TauxConversionInfos taux, InterfaceMySQL interfaceSql) {
    String sql = String.format(BASE_SQL, SQL_DATE_FORMAT.format(taux.getDate()),
        taux.getMonnaie_initiale().getCodeMonnaie(), taux.getMonnaie_finale().getCodeMonnaie(),
        taux.getTaux());

    try {
      interfaceSql.EnvoyerQuery(sql);
    } catch (SQLException e) {
      throw new MonException("Impossible d'inserer les taux", e);
    }
  }

  public TauxConversionInfos allerChercherTaux(Date date, MonnaieInfos monnaie_initiale,
                                                        MonnaieInfos monnaie_finale){
    TauxConversionInfos tauxconversion = allerChercherTauxDansMySQL(date, monnaie_initiale, monnaie_finale);
    if(tauxconversion == null){
        insererTauxDansLaTable(telechargerTauxPourDate(monnaie_initiale, monnaie_finale, date),
          new InterfaceMySQL());
       tauxconversion = allerChercherTauxDansMySQL(date, monnaie_initiale, monnaie_finale);
    }
    return tauxconversion;
  }

  private TauxConversionInfos allerChercherTauxDansMySQL(Date date, MonnaieInfos monnaie_initiale,
                                                        MonnaieInfos monnaie_finale){
    Float taux;
    ResultSet result;
    try {
      result = InterfaceMySQL.getInstance().RecupererDonnees(
      String.format("SELECT taux FROM tauxconversion WHERE Date = '%s' AND MonnaieInitiale = '%s' AND " +
          "MonnaieFinale = '%s'", SQL_DATE_FORMAT.format(date), monnaie_initiale.getCodeMonnaie(),
          monnaie_finale.getCodeMonnaie())
      );
    } catch (SQLException e) {
      throw new MonException("Mauvaise formulation de Query", e);
    }
    try {
      if (result.next()) {
        try {
          taux = Float.valueOf(result.getString(1));

        } catch (NumberFormatException nfe) {
          System.out.println("NumberFormatException: " + nfe.getMessage());
          throw new RuntimeException(nfe);
        }
        return new TauxConversionInfos(date, monnaie_initiale, monnaie_finale, taux);
      }

      else{
        return null;
      }

    } catch (SQLException e) {
      throw new MonException("", e);
    }
  }
}
